APCS in detail

(ARM Procedure Call Standard)

 

Introduction

The APCS, or ARM Procedure Call Standard, is a procedure calling and stack defining protocol used by assemblers, compilers and linkers. It should be APCS compliant, or it should output AOF files (unless a linker, in which case it should accept AOF files).
When this is achieved, you can set about using the best tools for a specific task, and not worry too much about compatibility as the act of being APCS compliant means you can call functions written in one language in functions written in another.

By way of example, when I was at college (back in '93), we had pascal inflicted on us. Well, ordinarily this might have presented a problem. Pascal is designed to be a Good Teaching Language, but GTL or not, it kept getting itself in the way of anything useful that should have been possible. The file handling was just orbiting in some other galaxy...
Thus, I wrote my basic stuff in pascal. I defined a bunch of external procedures, such as 'printf()' and 'fgetc()'. So when linking my pascal program, I linked it with the Shared C Library 'Stubs'. Hey presto, it worked!
Sadly, my hard work got me a D and a note not to be a smart ass. But I wasn't worried, I'm a believer that the education system de-educates. So while my classmates were scratching their heads trying to get Borland Turbo Pascal to do stuff, I knocked my code out in little time at all on RISC OS with an APCS compliant language. I was happily calling C functions from pascal, could have done vice versa. And if I wanted, writing some assembler and calling that would have been just as simple.

A major benefit of this is that an APCS library, once written and properly documented, can be utilised from an APCS language.

 

APCS précis

The ARM instruction set does not include procedure call instructions. In keeping with the RISC concept, this is provided by a set of rules. The success of a desktop-based language will, in the main, depend upon its interoperability with other languages, in particular C and assembler. A freebie pascal is available, and Intelligent Interfaces has a Fortran compiler. Other RISC OS languages probably exist, but you'll need to check somewhere like the Acorn CyberVillage to find out more.

The standard defines the use of registers - which may be corrupted and which must be preserved, and how arguments are passed. This is the minimum requirement.
Furthermore, a data structure is defined which will allow a backtracer to deconstruct the sequence of functions called, and details of parameters given. This information is invaluable when debugging software.

The standard only really defines external procedure calls. If your code/language wishes to do things differently, it may provided that the external interface is kept as documented. In practise, it is usually best to follow the specification. That way, nothing gets confused.

 

The design criteria for APCS was arrived at following a lot of testing and experimentation.

 

Registers

APCS registers are given names in order to help define their purpose. Thus, in much APCS code you will not see 'R0' and 'R14', you will see 'a1' and 'lr'. However any decent assembler will allow you to call the registers anything you choose.

Reg#  APCS  Purpose

R0    a1    argument 1 / integer result
R1    a2    argument 2
R2    a3    argument 3
R3    a4    argument 4
R4    v1    register variable
R5    v2    register variable
R6    v3    register variable
R7    v4    register variable
R8    v5    register variable
R9    v6    register variable
R10   sl    stack limit
R11   fp    frame pointer
R12   ip    temporary workspace
R13   sp    stack pointer (full descending stack)
R14   lr    link address on calls/workspace
R15   pc    program counter and processor status (26 bit)

F0    f0    floating point result
F1    f1    floating point scratch register
F2    f2    floating point scratch register
F3    f3    floating point scratch register
F4    f4    floating point preserved register
F5    f5    floating point preserved register
F6    f6    floating point preserved register
F7    f7    floating point preserved register

 

Argument passing

When control is passed to the target procedure, the following is valid: ... this is read from arthur prm - will need to look at prm4 to see if this information is valid...
Return to assembler index
Copyright © 2000 Richard Murray